home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr15 / ascgif20.zip / ASCGIF20.C next >
C/C++ Source or Header  |  1992-12-28  |  18KB  |  645 lines

  1. /*
  2.  * Ascii Gif Viewer Version 2.0 Dec (c) 1992 John Ferrell
  3.  * jwf10@juts.ccc.amdahl.com     Freeware.  Public Domain.
  4.  * Shows gif pictures using text characters.
  5.  */
  6. /* 7 changes for pc to mainframe portability. (search on 'mainframes') */
  7. /* some mini/workstations might need some of the pc definitions */
  8.  
  9. #include <string.h>
  10. #include <stdlib.h>               /* libc.h for mainframes, stdlib.h for pc */
  11. #include <stdio.h>
  12. #include <malloc.h>    /* malloc.h may not be needed with some mainframes */
  13.  
  14. #define UBYTE unsigned char    /* 8Bit */
  15. #define UWORD unsigned short    /* 16Bit */
  16. #define ULONG unsigned long     /* 32Bit  int for mainframes, long for pc */
  17. #define BOOL unsigned short
  18.  
  19. #define TRUE  1
  20. #define FALSE 0
  21.  
  22.  
  23. struct GIFdescriptor {
  24.    UWORD           gd_Width;
  25.    UWORD           gd_Height;
  26.    UBYTE           gd_ColInfo;
  27.    UBYTE           gd_BackGround;
  28.    UBYTE           gd_PixelAspect;
  29. };
  30.  
  31. struct ImageDesc {
  32.    UWORD           id_Left;
  33.    UWORD           id_Top;
  34.    UWORD           id_Width;
  35.    UWORD           id_Height;
  36.    UBYTE           id_Info;
  37. };
  38.  
  39. struct RGB {
  40.    UBYTE           rgb_Red;
  41.    UBYTE           rgb_Green;
  42.    UBYTE           rgb_Blue;
  43. };
  44.  
  45.  
  46. #define GIF_IMAGE       0x2C
  47. #define GIF_EXTENSION   0x21
  48. #define GIF_TERMINATOR  0x3B
  49. #define GIF_COMMENT_EXT 0xFE
  50.  
  51. void        *screen;       /* uncomment for pc, comment out for
  52.                  * mainframes */
  53.  
  54. struct GIFdescriptor gdesc;
  55.  
  56. UBYTE         **BitPlane;
  57. struct RGB      GlobalColourTable[256];
  58.  
  59. UBYTE           Map[256];
  60.  
  61. ULONG           ImageNumber;
  62.  
  63. FILE           *GIFfh = NULL;
  64. FILE           *CAPT = NULL;
  65.  
  66. void
  67. ERROR(str)
  68.    char           *str;
  69. {
  70.    printf(str);
  71.    exit(1);
  72. }
  73.  
  74. void
  75. FlipWord(word)
  76.    UWORD          *word;
  77. {
  78.    UBYTE           swap1;
  79.    UBYTE           swap2;
  80.    /*   swap1 = *word & 0xFF;          */  /* comment out for pc, needed for mainframes */
  81.    /*   swap2 = (*word & 0xFF00) >> 8; */  /* "                "                 */
  82.    /*   *word = swap1 << 8 | swap2;    */  /* "                "                 */
  83. }
  84.  
  85. static struct ImageDesc idesc;
  86. static struct RGB LocalColourTable[256];
  87.  
  88. static UWORD    Xpos, Ypos;
  89. static BOOL     interleave;
  90.  
  91. static UBYTE    LeaveStep[5] = {1, 8, 8, 4, 2};
  92. static UBYTE    LeaveFirst[5] = {0, 0, 4, 2, 1};
  93.  
  94. static int      ReadError;
  95. static UBYTE    CodeSize;
  96. static int      EOFCode;
  97. static UBYTE    ReadMask;
  98. static int      CompDataPointer;
  99. static int      CompDataCount;
  100. static UBYTE    CompData[256];
  101.  
  102. static UWORD    Prefix[4096];
  103. static UBYTE    Suffix[4096];
  104. static UBYTE    OutCode[1025];
  105.  
  106. static UBYTE    ByteBuf;
  107.  
  108. int
  109. ReadCode(fh)
  110.    FILE           *fh;
  111. {
  112.    register int    temp;
  113.    register int    DstMasked;
  114.    register int    DstMask;
  115.    long            size;
  116.    temp = 0;
  117.    DstMasked = 1L << CodeSize;
  118.    for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
  119.       if (!ReadMask) {
  120.      if (CompDataPointer == CompDataCount) {
  121.         if ((size = fgetc(fh)) == -1) {
  122.            printf("\nI/O Error during decompression.\n");
  123.            ReadError = 1;
  124.            return EOFCode;
  125.         }
  126.         if (fread((char *) CompData, 1, size, fh) != size) {
  127.            printf("\nI/O Error during decompression.\n");
  128.            ReadError = 1;
  129.            return EOFCode;
  130.         }
  131.         CompDataCount = size;
  132.         CompDataPointer = 0;
  133.      }
  134.      ReadMask = 1;
  135.      ByteBuf = CompData[CompDataPointer++];
  136.       }
  137.       if (ByteBuf & ReadMask)
  138.      temp |= DstMask;
  139.       ReadMask <<= 1;
  140.    }
  141.    return temp;
  142. }
  143.  
  144. void
  145. AddPixel(index)
  146.    UBYTE           index;
  147. {
  148.    register UWORD  XStore;
  149.    register UWORD  YStore;
  150.    XStore = Xpos + idesc.id_Left;
  151.    YStore = Ypos + idesc.id_Top;
  152.    BitPlane[YStore][XStore] = index;
  153.    if (++Xpos == idesc.id_Width) {
  154.       Xpos = 0;
  155.       Ypos += LeaveStep[interleave];
  156.       if (Ypos >= idesc.id_Height)
  157.      Ypos = LeaveFirst[++interleave];
  158.    }
  159. }
  160.  
  161. BOOL
  162. DoImage(fh)
  163.    FILE           *fh;
  164. {
  165.    register int    index;
  166.    register int    colours;
  167.    int             Code;
  168.    printf("Image #%ld encountered.\n", ImageNumber++);
  169.    if (fread((char *) &idesc, 1, 9, fh) != 9)
  170.       ERROR("Error reading image descriptor.\n");
  171.    FlipWord(&idesc.id_Left);
  172.    FlipWord(&idesc.id_Top);
  173.    FlipWord(&idesc.id_Width);
  174.    FlipWord(&idesc.id_Height);
  175.    interleave = idesc.id_Info & 1L << 6;
  176.    if (interleave)
  177.       interleave = 1;
  178.    printf("Xpos from %d to %d, Ypos from %d to %d, %sinterlaced.\n",
  179.       idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
  180.       idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
  181.       interleave ? "" : "not ");
  182.    if (idesc.id_Info & 1L << 7) {
  183.       colours = 1L << ((idesc.id_Info & 7) + 1);
  184.       printf("Local colour map contains %d entries.\n", colours);
  185.       for (index = 0; index < colours; index++)
  186.      if (fread(&LocalColourTable[index], 1, 3, fh) != 3)
  187.         ERROR("......Error reading local colour\n");
  188.    } else {
  189.       colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
  190.       for (index = 0; index < colours; index++)
  191.      LocalColourTable[index] = GlobalColourTable[index];
  192.    }
  193.    Xpos = Ypos = 0;
  194.  
  195.    {
  196.       int             MaxCode, ClearCode, CurCode, OldCode, InCode, FreeCode;
  197.       int             OutCount;
  198.       int             FirstFree;
  199.       UBYTE           InitCodeSize, FinChar, BitMask;
  200.       if ((CodeSize = fgetc(fh)) == -1)
  201.      ERROR("\n......I/O Error during decompression.\n");
  202.       ClearCode = 1L << CodeSize;
  203.       EOFCode = ClearCode + 1;
  204.       FreeCode = FirstFree = ClearCode + 2;
  205.       CodeSize++;
  206.       InitCodeSize = CodeSize;
  207.       MaxCode = 1L << CodeSize;
  208.       ReadError = ReadMask = OutCount = 0;
  209.       CompDataPointer = CompDataCount = 0;
  210.       BitMask = colours - 1;
  211.       Code = ReadCode(fh);
  212.       while (Code != EOFCode) {
  213.      if (ReadError)
  214.         return TRUE;
  215.      if (Code == ClearCode) {
  216.         CodeSize = InitCodeSize;
  217.         MaxCode = 1L << CodeSize;
  218.         FreeCode = FirstFree;
  219.         FinChar = CurCode = OldCode = Code = ReadCode(fh);
  220.         AddPixel(FinChar);
  221.      } else {
  222.         CurCode = InCode = Code;
  223.         if (CurCode >= FreeCode) {
  224.            CurCode = OldCode;
  225.            OutCode[OutCount++] = FinChar;
  226.         }
  227.         while (CurCode > BitMask) {
  228.            if (OutCount > 1024) {
  229.           printf("\nCorrupt GIF file (OutCount)\n");
  230.           return TRUE;
  231.            }
  232.            OutCode[OutCount++] = Suffix[CurCode];
  233.            CurCode = Prefix[CurCode];
  234.         }
  235.         FinChar = CurCode;
  236.         AddPixel(FinChar);
  237.         for (index = OutCount - 1; index >= 0; index--)
  238.            AddPixel(OutCode[index]);
  239.         OutCount = 0;
  240.         Prefix[FreeCode] = OldCode;
  241.         Suffix[FreeCode] = FinChar;
  242.         OldCode = InCode;
  243.         if (++FreeCode >= MaxCode) {
  244.            if (CodeSize < 12) {
  245.           CodeSize++;
  246.           MaxCode <<= 1;
  247.            }
  248.         }
  249.      }
  250.      Code = ReadCode(fh);
  251.       }
  252.    }
  253.    if ((Code = fgetc(fh)) == -1)
  254.       return TRUE;
  255.    if (Code != 0)
  256.       printf("Warning:  Unaligned packet.\n");
  257.    return FALSE;
  258. }
  259.  
  260. #define base 0
  261. int             gx = 79;
  262. int             gy = 24;
  263. int             bg = 1;
  264. int            max = 0;
  265.  
  266.  
  267. #define clors 16
  268.  
  269. char           *clortab[clors] =
  270. {".", ",", ":", ";", "=", "+", "i", "t", "I", "Y", "V", "X", "R", "B", "M", "W"};
  271.  
  272. char           *invcltab[clors] =
  273. {"W", "M", "B", "R", "X", "V", "Y", "I", "t", "i", "+", "=", ";", ":", ",", "."};
  274.  
  275.  
  276. void
  277. show(name)
  278.    char           *name;
  279. {
  280.    int             x, y, j, i;
  281.    int             ix, iy, ii, jj;
  282.    struct RGB      colour;
  283.    char            Cbuf[1];
  284.    long            best, z;
  285.    int             adj, top, bot, flag, cc, dx, dy, f, dcnt, inverse;
  286.  
  287.    adj = x = y = ix = iy = dx = dy = i = j = z = dcnt = f = inverse = 0;
  288.  
  289.    top = 0;
  290.    bot = 256;
  291.    cc = 1;
  292.    dx = 8;
  293.    dy = 16;
  294.    do {
  295.       if (!max)
  296.       if (adj && f){
  297.      flag = 'v';
  298.      adj = 0;
  299.       } else {
  300.      printf("\nAscgif20 (vi)ew (fF)ocus (zZ)oom (c)opy (l,r,u,d)=PAN (q)uit (h)elp: ");
  301.      while ((flag = getchar()) == (char) 10);
  302.      if (flag == 'v' || flag == 'z' || flag == 'Z' ||
  303.          flag == 'l' || flag == 'h' || flag == 'c' || flag == 'i' ||
  304.          flag == 'f' || flag == 'F' ||
  305.          flag == 'r' || flag == 'u' || flag == 'd' ||
  306.          flag == '1' || flag == '2' || flag == '3' || flag == '4');
  307.      else
  308.          return;
  309.       };
  310.       if (flag == 'v')
  311.      cc = 1;
  312.       if (flag == 'f'){
  313.      printf ("Adjusting focus...");
  314.      f = 1;
  315.      adj = 1;
  316.      top = 0;
  317.      bot = 256;
  318.       }
  319.       if (flag == 'F')
  320.      f = 0;
  321.       if (flag == 'i')
  322.      if (inverse == 1)
  323.         inverse = 0;
  324.      else
  325.         inverse = 1;
  326.       if (flag == '1') {
  327.      cc = 1;
  328.      printf("\nDefault Mix\n");
  329.       }
  330.       if (flag == '2') {
  331.      cc = 2;
  332.      printf("\nRed Mix Blocked\n");
  333.       }
  334.       if (flag == '3') {
  335.      cc = 3;
  336.      printf("\nGreen Mix Blocked\n");
  337.       }
  338.       if (flag == '4') {
  339.      cc = 4;
  340.      printf("\nBlue Mix Blocked\n");
  341.       }
  342.       if (flag == 'c') {
  343.      printf("\nAppending copy of screen to file ascgifs\n");
  344.      if (!(CAPT = fopen("ascgifs", "a")))
  345.         ERROR("Open error\n");
  346.      Cbuf[0] = 10;
  347.      if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  348.         ERROR("Unable to write to ascgifs.\n");
  349.      if (fwrite(name, 1, strlen(name), CAPT) != strlen(name))
  350.         ERROR("Unable to write to ascgifs.\n");
  351.       }
  352.       if (flag == 'u') {
  353.      if (f){
  354.         printf ("Adjusting focus, Moving up...");
  355.         adj = 1;
  356.         top = 0;
  357.         bot = 256;
  358.      };
  359.      if (iy >= dy * gy / 6)
  360.         iy = iy - dy * gy / 6;
  361.       };
  362.       if (flag == 'd') {
  363.      if (f){
  364.         printf ("Adjusting focus, Moving down...");
  365.         adj = 1;
  366.         top = 0;
  367.         bot = 256;
  368.      };
  369.      if (iy + dy * gy + 2 * dy < ((idesc.id_Height) << base))
  370.         iy = iy + dy * gy / 6;
  371.       };
  372.       if (flag == 'z') {
  373.      if (f){
  374.         adj = 1;
  375.         top = 0;
  376.         bot = 256;
  377.         printf ("Adjusting focus, Zooming in...");
  378.      };
  379.      dx -= 1;
  380.      dy -= 2;
  381.      if (dx < 1)
  382.         dx = 1;
  383.      else
  384.         ix = ix + dx * gx / 8;
  385.      if (dy < 2)
  386.         dy = 2;
  387.      else
  388.         iy = iy + dy * gy / 8;
  389.       };
  390.       if (flag == 'Z') {
  391.      if (f){
  392.         adj = 1;
  393.         printf ("Adjusting focus, Zooming out...");
  394.      };
  395.      dx = 8;
  396.      dy = 16;
  397.      top = 0;
  398.      bot = 256;
  399.      ix = 0;
  400.      iy = 0;
  401.       };
  402.       if (flag == 'r') {
  403.      if (f){
  404.         printf ("Adjusting focus, Moving right...");
  405.         adj = 1;
  406.         top = 0;
  407.         bot = 256;
  408.      };
  409.      if (ix + dx * gx + 2 * dx < ((idesc.id_Width) << base))
  410.         ix = ix + dx * gx / 6;
  411.       };
  412.       if (flag == 'l') {
  413.      if (f){
  414.         printf ("Adjusting focus, Moving left...");
  415.         adj = 1;
  416.         top = 0;
  417.         bot = 256;
  418.      };
  419.      if (ix >= dx * gx / 6)
  420.         ix = ix - dx * gx / 6;
  421.       };
  422.       if (idesc.id_Width / gx < dx){
  423.           dx = idesc.id_Width / gx;
  424.           if (dx < 1) dx = 1;
  425.       }
  426.       if (idesc.id_Height / gy < dy){
  427.           dy = idesc.id_Height / gy;
  428.           if (dy < 1) dy = 1;
  429.       }
  430.       if (max){
  431.       gx = idesc.id_Width;
  432.       gy = idesc.id_Height;
  433.       dx = dy = 1;
  434.       }
  435.       y = iy;
  436.       if (flag == 'h') {
  437.      printf("\nascgif(2.0) use: ascgif it.gif <M> <output width> <output height>\n");
  438.      printf("                 M shows to stdout with maximum dimensions\n");
  439.      printf("                 M invalid with <output width> <output height>\n");
  440.      printf("                 M Example:  ascgif it.gif M >bigpic\n");
  441.      printf("v = View the Gif\n");
  442.      printf("i = Toggle inverse screen\n");
  443.      printf("f = Focus the screen\n");
  444.      printf("F = Fuzzy but fast. Good for positioning.\n");
  445.      printf("z = Zoom in on the center\n");
  446.      printf("Z = Zoom out to normal size\n");
  447.      printf("c = Capture screen\n");
  448.      printf("l = Pan Left\n");
  449.      printf("r = Pan Right\n");
  450.      printf("u = Pan Up\n");
  451.      printf("d = Pan Down\n");
  452.      printf("1 = Default Mix (in Fuzzy mode only)\n");
  453.      printf("2 = Red Mix Blocked (in Fuzzy mode only)\n");
  454.      printf("3 = Green Mix Blocked (in Fuzzy mode only)\n");
  455.      printf("4 = Blue Mix Blocked (in Fuzzy mode only)\n");
  456.      printf("Any other character will quit\n");
  457.       } else {
  458.      for (j = 0; j < gy; j++) {
  459.         if (flag == 'c') {
  460.            Cbuf[0] = 10;
  461.            if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  462.           ERROR("Unable to write to ascgifs.\n");
  463.         }
  464.         if (!adj)
  465.            printf("\n");
  466.         x = ix;
  467.         for (i = 0; i < gx; i++) {
  468.            if (f) {
  469.           dcnt = 0;
  470.           best = 0;
  471.           for (jj = y; jj - y < dy; jj++) {
  472.              for (ii = x; ii - x < dx; ii++) {
  473.             colour = LocalColourTable[BitPlane[(jj >> base) + idesc.id_Top]
  474.                         [(ii >> base) + idesc.id_Left]];
  475.             z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
  476.             dcnt++;
  477.             best = (best * (dcnt - 1) + z) / dcnt;
  478.              }
  479.           };
  480.           if (best < bot)
  481.              bot = best;
  482.           if (best > top)
  483.              top = best;
  484.           if (top != bot)
  485.              best = (best - bot) * 256 / (top - bot);
  486.           if (best >= 256)
  487.              best = 255;
  488.           if (best < 0)
  489.              best = bg;
  490.  
  491.           if (!adj){
  492.              if (flag == 'c') {
  493.             if (inverse) {
  494.                Cbuf[0] = *invcltab[(best) * clors / 0x100];
  495.                if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  496.                   ERROR("Unable to write to ascgifs.\n");
  497.             } else {
  498.                Cbuf[0] = *clortab[(best) * clors / 0x100];
  499.                if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  500.                   ERROR("Unable to write to ascgifs.\n");
  501.             }
  502.              };
  503.              if (inverse)
  504.             printf(invcltab[(best) * clors / 0x100]);
  505.              else
  506.             printf(clortab[(best) * clors / 0x100]);
  507.           };
  508.           x += dx;
  509.           if (x > (idesc.id_Width << base))
  510.              break;
  511.            } else {
  512.           colour = LocalColourTable[BitPlane[(y >> base) + idesc.id_Top]
  513.                         [(x >> base) + idesc.id_Left]];
  514.           if (cc == 2) {
  515.              z = (colour.rgb_Green + colour.rgb_Blue) / 2;
  516.           } else if (cc == 3) {
  517.              z = (colour.rgb_Red + colour.rgb_Blue) / 2;
  518.           } else if (cc == 4) {
  519.              z = (colour.rgb_Red + colour.rgb_Green) / 2;
  520.           } else {
  521.              z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
  522.           };
  523.           if (flag == 'c') {
  524.              if (inverse) {
  525.             Cbuf[0] = *invcltab[(z) * clors / 0x100];
  526.             if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  527.                ERROR("Unable to write to ascgifs.\n");
  528.              } else {
  529.             Cbuf[0] = *clortab[(z) * clors / 0x100];
  530.             if (fwrite(Cbuf, 1, 1, CAPT) != 1)
  531.                ERROR("Unable to write to ascgifs.\n");
  532.              }
  533.           };
  534.           if (inverse)
  535.              printf(invcltab[(z) * clors / 0x100]);
  536.           else
  537.              printf(clortab[(z) * clors / 0x100]);
  538.           x += dx;
  539.           if (x > (idesc.id_Width << base))
  540.              break;
  541.            };
  542.         }
  543.         y += dy;
  544.         if (y > (idesc.id_Height << base))
  545.            break;
  546.      }
  547.       }
  548.       if (max)
  549.      return;
  550.       if (flag == 'c')
  551.          fclose(CAPT);
  552.    } while (TRUE);
  553. }
  554.  
  555. main(argc, argv)
  556.    int             argc;
  557.    char           *argv[];
  558. {
  559.    register int    index;
  560.    char            sig[7];
  561.    int             size;
  562.    int             error;
  563.    int             colours;
  564.    long            cmdcode;
  565.    if (argc < 2){
  566.      printf("ascgif(2.0) use: ascgif name.gif <M> <output width> <output height>\n");
  567.      printf("                 M shows to stdout with maximum dimensions\n");
  568.      printf("                 M invalid with <output width> <output height>\n");
  569.       ERROR("                 M Example:  ascgif it.gif M >bigpic\n");
  570.    }
  571.    if (!(GIFfh = fopen(argv[1],"rb")))
  572.                             /* "rb" for pc, "r" for SOME mainframes */
  573.       ERROR("Open error\n");
  574.    if (argc > 2) {
  575.       if ('M' == *argv[2]){
  576.           max = 1;
  577.        } else {
  578.         if (!(gx = atoi(argv[2])))
  579.            ERROR("3rd parameter not numeric, (width)\n");
  580.             if (!(gy = atoi(argv[3])))
  581.            ERROR("4th parameter not numeric, (height)\n");
  582.      };
  583.    } else {
  584.       gx = 79;
  585.       gy = 24;
  586.    };
  587.    sig[6] = '\0';
  588.    if (fread(sig, 1, 6, GIFfh) != 6 || strcmp("GIF87a", sig))
  589.       ERROR("Not an 87a GIF file...\n");
  590.    if (fread((char *) &gdesc, 1, 7, GIFfh) != 7)
  591.       ERROR("Error reading screen descriptor\n");
  592.    FlipWord(&gdesc.gd_Width);
  593.    FlipWord(&gdesc.gd_Height);
  594.    printf("Ascgif Ver 2.0\n");
  595.    printf("Signature = \"%s\", Width = %u, Height = %u\n",
  596.       sig, gdesc.gd_Width, gdesc.gd_Height);
  597.    colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
  598.    if (!(gdesc.gd_ColInfo & 1L << 7)) {
  599.       printf("No global colour map supplied, using internal.\n");
  600.       for (index = 0; index < colours; index++) {
  601.      GlobalColourTable[index].rgb_Red =
  602.         GlobalColourTable[index].rgb_Green =
  603.         GlobalColourTable[index].rgb_Blue = index;
  604.       }
  605.    } else {
  606.       printf("Global colour map contains %d entries.\n", colours);
  607.       for (index = 0; index < colours; index++)
  608.      if (fread(&GlobalColourTable[index], 1, 3, GIFfh) != 3)
  609.         ERROR("Error reading global colour\n");
  610.    }
  611.    size = ((gdesc.gd_Width + 7) / 8) + 1;
  612.    size += (size + 127) >> 7; /* use far,_fmalloc for pc, not for mainframes */
  613.    if (!(BitPlane = (UBYTE far **) _fmalloc(gdesc.gd_Height * sizeof(UBYTE *))))
  614. /* if (!(BitPlane = (UBYTE **) malloc(gdesc.gd_Height * sizeof(UBYTE *)))) */
  615.       ERROR("Not enough memory\n");
  616.    size = (gdesc.gd_Width + 1) * sizeof(UBYTE);
  617.    for (index = 0; index < gdesc.gd_Height; index++)
  618.      /* use far,_fmalloc for pc, not for mainframes */
  619.       if (!(BitPlane[index] = (UBYTE far *) _fmalloc(size)))
  620.  /*   if (!(BitPlane[index] = (UBYTE *) malloc(size)))    */
  621.      ERROR("Not enough memory\n");
  622.    ImageNumber = 1;
  623.    for (error = FALSE; error == FALSE;) {
  624.       if ((cmdcode = fgetc(GIFfh)) == -1)
  625.      break;
  626.       if (cmdcode ==
  627.       GIF_IMAGE) {
  628.      error = DoImage(GIFfh);
  629.       } else if (cmdcode ==
  630.          GIF_EXTENSION) {
  631.      error = TRUE;
  632.       } else if (cmdcode ==
  633.          GIF_TERMINATOR) {
  634.      show(argv[1]);
  635.      break;
  636.       } else {
  637.      printf("Unknown directive encountered.\n");
  638.      error = TRUE;
  639.       }
  640.    }
  641.    printf("End of GIF session\n");
  642.  
  643.    return (0);
  644. }
  645.